﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using XboxUserInterface.Variables;
using XboxUserInterface.Keys;
using XboxUserInterface.Properties;
using XboxUserInterface.Settings;
using MyCustomControls;
using System.Threading;

namespace XboxUserInterface.Forms
{
    public partial class SettingsForm : Form
    {
        /// <summary>
        /// KeyMap to change
        /// </summary>
        private KeyMap _map;

        /// <summary>
        /// Indicates whether edits have been made
        /// </summary>
        private bool _edits = false;

        /// <summary>
        /// The KeyMap being edited by the instance
        /// </summary>
        public KeyMap Map
        {
            get { return _map; }
            set { _map = value; }
        }

        /// <summary>
        /// Creates a new SettingsForm referencing an existing KeyMap
        /// </summary>
        /// <param name="map">KeyMap to reference</param>
        public SettingsForm(KeyMap map)
        {
            InitializeComponent();
            Map = map;
        }

        /// <summary>
        /// Changes the paramaters of each of the SettingDropDown controls to correspond to a set of key codes
        /// </summary>
        /// <param name="sender">SettingsForm sending the request</param>
        /// <param name="e">Information for the request</param>
        private void SettingsForm_Load(object sender, EventArgs e)
        {
            string[] analogs = Enum.GetNames(typeof(AnalogFunctions));
            string[] digitals = Enum.GetNames(typeof(DigitalFunctions));

            foreach (Control d in this.Controls)
            {
                if (d.GetType() == typeof(SettingDropDown))
                {
                    SettingDropDown _d = (SettingDropDown)d;
                    
                    if (_d.Type == DropDownType.Analog)
                        foreach (string s in analogs)
                            _d.Items.Add(s);
                        //foreach (String s in Enum.GetNames(typeof(AnalogFunctions)))
                        //    _d.Items.Add(Enum.Parse(typeof(AnalogFunctions), s).ToString());

                    if (_d.Type == DropDownType.Digital)
                        foreach (string s in digitals)
                            _d.Items.Add(s);
                        //foreach (String s in Enum.GetNames(typeof(DigitalFunctions)))
                        //    _d.Items.Add(Enum.Parse(typeof(DigitalFunctions), s).ToString());

                    _d.SelectedIndexChanged += new EventHandler(_d_SelectedIndexChanged);
                }
            }

            foreach (Key k in Map.Keys)
            {
                SettingDropDown blarg = (SettingDropDown)(Controls.Find(k.GamePadKey.ToString(), true)[0]);
                blarg.SelectedIndex = blarg.Items.IndexOf(k.KeyCode.ToString());
            }

            _edits = false;
        }

        /// <summary>
        /// Changes the Key corresponding to a SettingDropDown when it is changed and flags that edits have occurred.
        /// </summary>
        /// <param name="sender">SettingsForm sending the request</param>
        /// <param name="e">Information for the request</param>
        void _d_SelectedIndexChanged(object sender, EventArgs e)
        {
            _edits = true;
            SettingDropDown d = (SettingDropDown)sender;
            foreach (Key k in Map.Keys)
                if (k.GamePadKey.ToString() == d.Name)
                    k.KeyCode = (KeyboardFunction)Enum.Parse(typeof(KeyboardFunction), d.Items[d.SelectedIndex].ToString());
        }

        /// <summary>
        /// Saves the current scheme
        /// </summary>
        /// <param name="sender">SettingsForm sending the request</param>
        /// <param name="e">Information for the request</param>
        private void button3_Click(object sender, EventArgs e)
        {
            saveScheme();
            this.Close();
        }

        /// <summary>
        /// If the form has been edited and not been saved, prompts for user input and closes the form.
        /// </summary>
        /// <param name="sender">SettingsForm sending the request</param>
        /// <param name="e">Information for the request</param>
        private void SettingsForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_edits)
            {
                DialogResult d = MessageBox.Show("You have unsaved data.  Would you like to save now?", "Save...", MessageBoxButtons.YesNoCancel,MessageBoxIcon.Question);

                switch (d)
                {
                    case DialogResult.Yes:
                        saveScheme();
                        break;
                    case DialogResult.No:
                        break;
                    case DialogResult.Cancel:
                        e.Cancel = true;
                        break;
                }
            }
        }

        /// <summary>
        /// Saves the scheme data back into Globals
        /// </summary>
        private void saveScheme()
        {
            NameInput n = new NameInput(this);

            if (string.IsNullOrEmpty(Map.SchemeName))
            {
                n.Show();
                //while (n.Open) Thread.Sleep(10);
            }

            for (int i = 0; i < Globals.Schemes.Count; i++)
                if (Globals.Schemes[i].SchemeName == Map.SchemeName)
                    Globals.Schemes.RemoveAt(i);

            Globals.Schemes.Add(Map);
            _edits = false;

            Operations.SaveGlobalSchemes();
        }
    }
}
